home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / rewrite / locks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  6.1 KB  |  253 lines

  1. /* 
  2.  * $Header: /private/postgres/src/rewrite/RCS/locks.c,v 2.12 1991/11/17 21:08:16 mer Exp $
  3.  */
  4.  
  5. #include "tmp/postgres.h"        /* for oid defs */
  6. #include "utils/log.h"            /* for elog */
  7. #include "parser/parse.h"        /* atom defs */
  8. #include "nodes/pg_lisp.h"        /* lisp support package */
  9. #include "rules/prs2locks.h"        /* prs2 lock definitions */
  10. #include "rules/prs2.h"            /* prs2 routine headers */
  11. #include "nodes/primnodes.h"        /* Var node def */
  12. #include "parser/parsetree.h"        /* parsetree manip routines */
  13. #include "catalog/syscache.h"        /* for SearchSysCache */
  14. #include "./locks.h"            /* for rewrite specific lock defns */
  15. char
  16. PutRelationLocks ( rule_oid, ev_oid, ev_attno,
  17.            ev_type, is_instead )
  18.      oid rule_oid;
  19.      oid ev_oid;
  20.      int ev_attno;
  21.      int ev_type;
  22.      bool is_instead;
  23. {
  24.     char locktype = (LockIsRewrite | LockIsActive) ;
  25.  
  26.     switch ( ev_type ) {
  27.       case RETRIEVE:
  28.     locktype |= EventIsRetrieve;
  29.     break;
  30.       case REPLACE:
  31.     locktype |= EventIsReplace;
  32.     break;
  33.       case APPEND:
  34.     locktype |= EventIsAppend;
  35.     break;
  36.       case DELETE:
  37.     locktype |= EventIsDelete;
  38.     break;
  39.       default:
  40.     elog(WARN,"unknown event type %d",ev_type );
  41.     }
  42.     
  43.     if ( is_instead ) {
  44.     locktype |=  DoInstead;
  45.     }
  46. #ifdef DEPRECATED
  47.     switch ( ac_type ) {
  48.       case      0:        /* temp support for instead nothing */
  49.       case APPEND:
  50.       case DELETE:
  51.     locktype |= DoOther;
  52.     break;
  53.       case RETRIEVE:
  54.     if ( ev_type == RETRIEVE ) {
  55.         /* retrieve-retrieve is really retrieve-relation 
  56.          * unless it is over a ".all" targetlist, in which
  57.          * case, it has been transformed by calling routine
  58.          * into a REPLACE-CURRENT action
  59.          */
  60.         locktype |= DoExecuteProc;
  61.     } else {
  62.         locktype |= DoOther;
  63.     }
  64.     break;
  65.       case REPLACE:
  66.     if (ac_result == 1 || ac_result == 2 ) {
  67.         locktype |= DoReplaceCurrentOrNew;
  68.     } else {
  69.         locktype |= DoOther;
  70.     }
  71.     break;
  72.       default:
  73.     elog(WARN,"don't know action type");
  74.     /* NOTREACHED */
  75.     break;
  76.     }
  77. #endif DEPRECATED
  78.     return ( locktype );
  79. }
  80.  
  81.  
  82. /*
  83.  * ThisLockWasTriggered
  84.  *
  85.  * walk the tree, if there we find a varnode,
  86.  * we check the varattno against the attnum
  87.  * if we find at least one such match, we return true
  88.  * otherwise, we return false
  89.  */
  90.  
  91.  
  92. bool
  93. ThisLockWasTriggered ( varno, attnum, parse_subtree )
  94.      int varno;
  95.      AttributeNumber attnum;
  96.      List parse_subtree;
  97. {
  98.     List i;
  99.  
  100.     foreach ( i , parse_subtree ) {
  101.  
  102.     Node temp = (Node)CAR(i);
  103.  
  104.     if ( !null(temp) ) {
  105.         if ( IsA(temp,Var) && 
  106.          ( varno == get_varno((Var)temp)) && 
  107.          (( get_varattno((Var)temp) == attnum ) || attnum == -1 ) ) {
  108.              return ( true );
  109.         } else if ( IsA(temp,LispList) &&
  110.             ThisLockWasTriggered ( varno, attnum, (List) temp )) {
  111.                 return (true);
  112.         }
  113.     }
  114.     }
  115.     return ( false );
  116. }
  117.  
  118. /*
  119.  * MatchRetrieveLocks
  120.  * - looks for varnodes that match the rulelock
  121.  * (where match(foo) => varno = foo.varno AND 
  122.  *                    ( (oneLock->attNum == -1) OR
  123.  *                  (oneLock->attNum = foo.varattno ))
  124.  *
  125.  * RETURNS: list of rulelocks
  126.  * XXX can be improved by searching for all locks
  127.  * at once by NOT calling ThisLockWasTriggered
  128.  */
  129. List
  130. MatchRetrieveLocks ( rulelocks , varno , parse_subtree  )
  131.      RuleLock rulelocks;
  132.      int varno;
  133.      List parse_subtree;
  134. {
  135.     int nlocks        = 0;
  136.     int i         = 0;
  137.     Prs2OneLock oneLock    = NULL;
  138.     List real_locks     = NULL;
  139.  
  140.     Assert ( rulelocks != NULL );
  141.  
  142.     nlocks = prs2GetNumberOfLocks ( rulelocks );
  143.  
  144.     for ( i = 0 ; i < nlocks ; i++ ) {
  145.     oneLock = prs2GetOneLockFromLocks ( rulelocks , i );
  146.     if ( IsActive(oneLock) && IsRewrite(oneLock) &&
  147.         LockEventIsRetrieve(oneLock)) {
  148.         if ( ThisLockWasTriggered ( varno,
  149.                        oneLock->attributeNumber,
  150.                        parse_subtree )) 
  151.           real_locks = nappend1 ( real_locks, (LispValue)oneLock );
  152.     }
  153.     }
  154.  
  155.     return ( real_locks );
  156.  
  157. }
  158.  
  159.  
  160. /*
  161.  * MatchLocks
  162.  * - match the list of locks, 
  163.  */
  164. List
  165. MatchLocks ( locktype, rulelocks , varno , user_parsetree )
  166.      Prs2LockType locktype;
  167.      RuleLock rulelocks;
  168.      int varno;
  169.      List user_parsetree;
  170. {
  171.     List real_locks         = NULL;
  172.     List root;
  173.     Prs2OneLock oneLock        = NULL;
  174.     int nlocks            = 0;
  175.     int i            = 0;
  176.     List actual_result_reln    = NULL;
  177.     
  178.     Assert ( rulelocks != NULL ); /* we get called iff there is some lock */
  179.     Assert ( user_parsetree != NULL );
  180.  
  181.     root = parse_root ( user_parsetree );
  182.  
  183.     actual_result_reln =  root_result_relation (root);
  184.  
  185.     if (root_command_type(root) != RETRIEVE) 
  186.     if (CInteger ( actual_result_reln ) != varno ) {
  187.         return ( NULL );
  188.     }
  189.  
  190.     nlocks = prs2GetNumberOfLocks ( rulelocks );
  191.  
  192.     for ( i = 0 ; i < nlocks ; i++ ) {
  193.     oneLock = prs2GetOneLockFromLocks ( rulelocks , i );
  194.     if ( IsActive(oneLock) && IsRewrite(oneLock) &&
  195.         Event(oneLock) == locktype )  {
  196.         if (root_command_type(root) == RETRIEVE) {
  197.         if ( ThisLockWasTriggered ( varno,
  198.                        oneLock->attributeNumber,
  199.                        user_parsetree ))
  200.             real_locks = nappend1 ( real_locks, (LispValue)oneLock );
  201.         }
  202.         else real_locks = nappend1 ( real_locks, (LispValue)oneLock );
  203.     } /* if lock is suitable */
  204.     } /* for all locks */
  205.     
  206.     return ( real_locks );
  207. }
  208.  
  209. List
  210. MatchReplaceLocks ( rulelocks , current_varno, user_parsetree )
  211.      RuleLock rulelocks;
  212.      int current_varno;
  213.      List user_parsetree;
  214. {
  215.     /*
  216.      * currently, don't support LockTypeReplaceWrite
  217.      * which has some kind of on delete do replace current 
  218.      */
  219.  
  220.     return ( MatchLocks ( EventIsReplace , 
  221.               rulelocks, current_varno , user_parsetree ));
  222. }
  223.  
  224. List
  225. MatchAppendLocks ( rulelocks , current_varno, user_parsetree )
  226.      RuleLock rulelocks;
  227.      int current_varno;
  228.      List user_parsetree;
  229. {
  230.     /*
  231.      * currently, don't support LockTypeAppendWrite
  232.      * which has some kind of on delete do replace current 
  233.      */
  234.     return ( MatchLocks ( EventIsAppend , 
  235.              rulelocks, current_varno , user_parsetree ));
  236. }
  237.  
  238. List
  239. MatchDeleteLocks ( rulelocks , current_varno, user_parsetree )
  240.      RuleLock rulelocks;
  241.      int current_varno;
  242.      List user_parsetree;
  243. {
  244.     /*
  245.      * currently, don't support LockTypeDeleteWrite
  246.      * which has some kind of on delete do replace current 
  247.      */
  248.  
  249.     return ( MatchLocks ( EventIsDelete , 
  250.              rulelocks, current_varno , user_parsetree ));
  251. }
  252.  
  253.